package com.ddl.service.impl;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.ddl.dao.IMDao;
import com.ddl.util.DateUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import com.alibaba.fastjson.JSONObject;

/**
 * 网易IM单聊service
 * 
 * @author 说明：其他功能以及非必须参数的拓展使用，请自行参考网易IM文档。
 * 
 */
@Service
public class IMSingleChatService {
//	@Value("${WANGYI_IM_Key}")
//	private String appKey;
//	@Value("${WANGYI_IM_Secret}")
//	private String appSecret;
	
	private String appKey="83b351628bf0697f7db14ba43d6c800d";
	private String appSecret="492a12d5c086";
	
	private IMDao imDao = new IMDao();

	/*-------------------------------------网易云通讯ID开始---------------------------------------------*/
	/**
	 * 创建网易云通信ID：注册网易云IM
	 * @param accid  网易云通信ID，最大长度32字符，必须保证一个APP内唯一,不区分大小写，会统一小写处理
	 * @param token  网易云通信ID可以指定登录token值，最大长度128字符，并更新，如果未指定，会自动生成token，并在创建成功后返回
	 * @return
	 * @throws Exception
	 */
	public JSONObject registeredIMID(String accid, String token) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("token", token);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/create.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 网易云通信ID更新：疑似修改IM登录密码token
	 * @param accid  网易云通信ID，最大长度32字符，必须保证一个APP内唯一
	 * @param token  网易云通信ID可以指定登录token值，最大长度128字符，并更新，如果未指定，会自动生成token，并在创建成功后返回
	 * @return
	 * @throws Exception
	 */
	public JSONObject modifyIMToken(String accid, String token) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("token", token);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/update.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 更新并获取新token:一般用于网易云通信ID修改密码，找回密码或者第三方有需求获取新的token。
	 * @param accid  网易云通信ID，最大长度32字符，必须保证一个APP内唯一
	 * @return
	 * @throws Exception
	 */
	public JSONObject getNewToken(String accid) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/refreshToken.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 封禁网易云通信ID:第三方禁用某个网易云通信ID的IM功能；封禁后，此ID将不能登陆网易云通信imserver。
	 * @param accid  网易云通信ID，最大长度32字符，必须保证一个APP内唯一
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject bannedIMID(String accid) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/block.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 解禁网易云通信ID:解禁被封禁的网易云通信ID
	 * @param accid  网易云通信ID，最大长度32字符，必须保证一个APP内唯一
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject liftBannedIMID(String accid) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/unblock.action", map, appKey, appSecret);
		return result;
	}
	/*-------------------------------------网易云通讯ID结束---------------------------------------------*/

	/*--------------------------------------用户名片开始---------------------------------------------*/
	/**
	 * 更新用户名片
	 * @param accid  网易云通信ID，最大长度32字符，必须保证一个APP内唯一
	 * @param name  用户昵称，最大长度64字符
	 * @param icon  用户头像，最大长度1024字节
	 * @param sign  用户签名，最大长度256字符
	 * @param gender  用户性别，0表示未知，1表示男，2女表示女，其它会报参数错误
	 * @return  code=200表示成功
	 * @throws Exception
	 */
	public JSONObject updateUserInfo(String accid, String name, String icon, String sign, int gender) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("name", name);
		map.put("icon", icon);
		map.put("sign", sign);
		map.put("gender", gender+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/updateUinfo.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 获取用户名片：可批量
	 * @param accids 用户帐号（例如：JSONArray对应的accid串，如：["zhangsan"]，如果解析出错，会报414）（一次查询最多为200）
	 * @return  code=200表示成功
	 * @throws Exception
	 */
	public JSONObject getUserInfoList(String accids) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accids", accids);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/getUinfos.action", map, appKey, appSecret);
		return result;
	}
	/*--------------------------------------用户名片结束---------------------------------------------*/

	/*--------------------------------------用户关系托管开始---------------------------------------------*/
	/**
	 * 加好友
	 * @param accid  加好友发起者accid
	 * @param faccid  加好友接收者accid
	 * @param type  1直接加好友，2请求加好友，3同意加好友，4拒绝加好友
	 * @param msg  加好友对应的请求消息，第三方组装，最长256字符
	 * @return  code=200表示成功
	 * @throws Exception
	 */
	public JSONObject addFriend(String accid, String faccid, int type, String msg) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("faccid", faccid);
		map.put("type", type+"");
		map.put("msg", msg);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/friend/add.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 更新好友相关信息，如加备注名，必须是好友才可以
	 * @param accid 发起者accid
	 * @param faccid 要修改朋友的accid
	 * @param alias 给好友增加备注名，限制长度128
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject updateFriendInfo(String accid, String faccid, String alias) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("faccid", faccid);
		map.put("alias", alias);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/friend/update.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 删除好友
	 * @param accid 发起者accid
	 * @param faccid 要删除朋友的accid
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject deleteFriend(String accid, String faccid) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("faccid", faccid);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/friend/delete.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 获取好友关系：查询某时间点起到现在有更新的双向好友
	 * @param accid 发起者accid
	 * @param updatetime 更新时间戳，接口返回该时间戳之后有更新的好友列表
	 * @return code=200表示成功;如果给好友设置了备注名,那么也会在好友列表中返回
	 * @throws Exception
	 */
	public JSONObject getFriendList(String accid, Long updatetime) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("updatetime", updatetime+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/friend/get.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 设置黑名单/静音：拉黑/取消拉黑；设置静音/取消静音
	 * @param accid 用户帐号
	 * @param targetAcc 被加黑或加静音的帐号
	 * @param relationType 本次操作的关系类型,1:黑名单操作，2:静音列表操作
	 * @param value 操作值，0:取消黑名单或静音，1:加入黑名单或静音
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject setBlacklistOrMute(String accid, String targetAcc, int relationType, int value) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		map.put("targetAcc", targetAcc);
		map.put("relationType", relationType+"");
		map.put("value", value+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/setSpecialRelation.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 查看指定用户的黑名单和静音列表
	 * @param accid 用户帐号
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject listBlackAndMuteList(String accid) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("accid", accid);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/user/listBlackAndMuteList.action", map, appKey, appSecret);
		return result;
	}
	/*--------------------------------------用户关系托管结束---------------------------------------------*/

	/*--------------------------------------消息功能开始---------------------------------------------*/
	/**
	 * 发送普通消息:给用户或者高级群发送普通消息，包括文本，图片，语音，视频和地理位置等
	 * @param from  发送者accid，用户帐号
	 * @param ope  0：点对点个人消息，1：群消息（高级群），其他返回414
	 * @param to  ope==0是表示accid即用户id，ope==1表示tid即群id
	 * @param type  0 表示文本消息,1 表示图片，2 表示语音，3 表示视频，4 表示地理位置信息，6 表示文件，100 自定义消息类型（特别注意，对于未对接易盾反垃圾功能的应用，该类型的消息不会提交反垃圾系统检测）
	 * @param body 消息内容，是一个json串，如{"msg":"哈哈哈"}
	 * @param 其他非必须参数参考网易开发文档
	 * @return  code=200表示成功
	 * @throws Exception
	 */
	public JSONObject sendMsg(String from, int ope, String to, int type, String body) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("from", from);
		map.put("ope", ope+"");
		map.put("to", to);
		map.put("type", type+"");
		map.put("body", body);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/sendMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 批量发送点对点普通消息:消息群发，只能针对个人
	 * @param fromAccid 发送者accid，用户帐号
	 * @param toAccids  JSONArray对应的接受者的accid，如["aaa","bbb"]，如果解析出错，会报414错误，限500人
	 * @param type 0 表示文本消息,1 表示图片，2 表示语音，3 表示视频，4 表示地理位置信息，6 表示文件，100 自定义消息类型（特别注意，对于未对接易盾反垃圾功能的应用，该类型的消息不会提交反垃圾系统检测）
	 * @param body 消息内容，是一个json传，如{"msg":"哈哈哈"}
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject sendBatchMsg(String fromAccid, String toAccids, int type, String body) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("fromAccid", fromAccid);
		map.put("toAccids", toAccids);
		map.put("type", type+"");
		map.put("body", body);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/sendBatchMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 发送自定义系统通知:如某个用户给另一个用户发送好友请求信息时发送系统自定义通知;接收系统通知是在前端实现的
	 * @param from 发送者accid，用户帐号
	 * @param to  msgtype==0是表示accid即用户id，msgtype==1表示tid即群id
	 * @param msgtype  0：点对点自定义通知，1：群消息自定义通知，其他返回414
	 * @param attach  自定义通知内容，第三方组装的字符串，建议是JSON串，最大长度4096字符
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject sendAttachMsg(String from, String to, int msgtype, String attach) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("from", from);
		map.put("to", to);
		map.put("msgtype", msgtype+"");
		map.put("attach", attach);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/sendAttachMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 批量发送点对点自定义系统通知：支持点对点类型
	 * @param fromAccid  发送者accid，用户帐号
	 * @param toAccids  JSONArray对应的接受者的accid，如["aaa","bbb"]，如果解析出错，会报414错误，限500人
	 * @param attach  自定义通知内容，第三方组装的字符串，建议是JSON串，最大长度4096字符
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject sendBatchAttachMsg(String fromAccid, String toAccids, String attach) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("fromAccid", fromAccid);
		map.put("toAccids", toAccids);
		map.put("attach", attach);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/sendBatchAttachMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 文件上传：字符流需要base64编码，最大15M
	 * @param content  字符流base64串(Base64.encode(bytes)) ，最大15M的字符流
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject upload(String content) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("content", content);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/upload.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 文件上传（multipart方式）
	 * @param content  最大15M的字符流
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject fileUpload(MultipartFile content) throws Exception{
		//把MultipartFile转成字符流
		InputStream inputStream = content.getInputStream();
        InputStreamReader is = new InputStreamReader(inputStream);
        BufferedReader br = new BufferedReader(is);
        StringBuffer sBuffer=new StringBuffer();
        String s = "";
        while ((s = br.readLine()) != null) {
        	sBuffer.append(s);
        }
		//传递参数
		Map<String, String> map = new HashMap<String, String>();
		map.put("content", sBuffer.toString());
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/fileUpload.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 消息撤回:可以撤回一定时间内的点对点与群消息
	 * @param deleteMsgid  要撤回消息的msgid
	 * @param timetag  要撤回消息的创建时间
	 * @param type  7:表示点对点消息撤回，8:表示群消息撤回，其它为参数错误
	 * @param from  发消息的accid
	 * @param to  如果点对点消息，为接收消息的accid,如果群消息，为对应群的tid
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject recall(String deleteMsgid, Long timetag, int type, String from, String to) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("deleteMsgid", deleteMsgid);
		map.put("timetag", timetag+"");
		map.put("type", type+"");
		map.put("from", from);
		map.put("to", to);
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/msg/recall.action", map, appKey, appSecret);
		return result;
	}
	/*--------------------------------------消息功能结束---------------------------------------------*/

	/*--------------------------------------历史记录开始---------------------------------------------*/
	/**
	 * 单聊云端历史消息查询
	 * @param from  发送者accid
	 * @param to  接收者accid
	 * @param begintime  开始时间，ms
	 * @param endtime  截止时间，ms
	 * @param limit  本次查询的消息条数上限(最多100条),小于等于0，或者大于100，会提示参数错误
	 * @param reverse  1按时间正序排列，2按时间降序排列。其它返回参数414错误.默认是按降序排列
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功,其中msgs对应的历史消息格式说明见网易开发文档，下面是普通文本消息示例，
	 * {"msgid":111848407349,"from":"manzi","body":{"msg":"猪蹄子！"},"sendtime":1539584225865,"type":0}
	 * @throws Exception
	 */
	public JSONObject querySessionMsg(String from, String to, String begintime, String endtime, int limit, int reverse) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("from", from);
		map.put("to", to);
		map.put("begintime", begintime);
		map.put("endtime", endtime);
		map.put("limit", limit+"");
		map.put("reverse", reverse+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/history/querySessionMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 群聊云端历史消息查询:查询存储在网易云通信服务器中的群聊天历史消息，只能查询在保存时间范围内的消息
	 * @param tid  群id
	 * @param accid  查询用户对应的accid
	 * @param begintime  开始时间，ms
	 * @param endtime  截止时间，ms
	 * @param limit  本次查询的消息条数上限(最多100条),小于等于0，或者大于100，会提示参数错误
	 * @param reverse  1按时间正序排列，2按时间降序排列。其它返回参数414错误.默认是按降序排列
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功,其中msgs对应的历史消息格式说明见网易开发文档，注意，群聊的历史信息还可能会包含群内系统通知
	 * {"msgs":[{"msgid":96246494239129602,"from":"manzi","body":{"msg":"wa,这是群聊？"},"type":0,"sendtime":1539152440521},{"msgid":96246494239129601,"from":"gailun","body":{"accids":["manzi"],"ope":0,"tname":"英雄联盟","updatetime":1539151517911,"tid":1434184525},"type":5,"sendtime":1539151518114}],"code":200,"size":2,"tid":1434184525}
	 * @throws Exception
	 */
	public JSONObject queryTeamMsg(String tid, String accid, String begintime, String endtime, int limit, int reverse) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("tid", tid);
		map.put("accid", accid);
		map.put("begintime", begintime);
		map.put("endtime", endtime);
		map.put("limit", limit+"");
		map.put("reverse", reverse+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/history/queryTeamMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 聊天室云端历史消息查询:此接口有频控限制，每分钟可调用不超过1200次
	 * @param roomid  聊天室id
	 * @param accid  用户账号
	 * @param timetag  查询的时间戳锚点，13位。reverse=1时timetag为起始时间戳，reverse=2时timetag为终止时间戳
	 * @param limit  本次查询的消息条数上限(最多200条),小于等于0，或者大于200，会提示参数错误
	 * @param reverse  1按时间正序排列，2按时间降序排列。其它返回参数414错误。默认是2按时间降序排列
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject queryChatroomMsg(Long roomid, String accid, Long timetag, int limit, int reverse) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("roomid", roomid+"");
		map.put("accid", accid);
		map.put("timetag", timetag+"");
		map.put("limit", limit+"");
		map.put("reverse", reverse+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/history/queryChatroomMsg.action", map, appKey, appSecret);
		return result;
	}
	
	/**
	 * 删除聊天室云端历史消息
	 * @param roomid  聊天室id
	 * @param fromAcc  消息发送者的accid
	 * @param msgTimetag  消息的时间戳，单位毫秒，应该拿到原始消息中的时间戳为参数
	 * @param 其他非必须参数参考网易开发文档
	 * @return code=200表示成功
	 * @throws Exception
	 */
	public JSONObject deleteHistoryChatroomMsg(Long roomid, String fromAcc, Long msgTimetag) throws Exception{
		Map<String, String> map = new HashMap<String, String>();
		map.put("roomid", roomid+"");
		map.put("fromAcc", fromAcc);
		map.put("msgTimetag", msgTimetag+"");
		JSONObject result = imDao.IMHttpClientPost("https://api.netease.im/nimserver/chatroom/deleteHistoryMessage.action", map, appKey, appSecret);
		return result;
	}
	/*--------------------------------------历史记录结束---------------------------------------------*/
	public static void main(String[] args) {
		try {
			IMSingleChatService imSingleChatService=new IMSingleChatService();
			System.out.println(imSingleChatService.registeredIMID("15","123456"));
			String[] s={"5"};
			System.out.println(imSingleChatService.getUserInfoList(JSONArray.toJSON(s).toString()));

//			Map<String,Object> map=new HashMap<>();
//			map.put("msg","你好");
////			System.out.println(imSingleChatService.sendMsg("1",0,"2",0, JSONObject.toJSONString(map)));
			JSONObject jsonObject=imSingleChatService.querySessionMsg("15","5",String.valueOf(DateUtil.nDayAfter(-3,new Date()).getTime()),String.valueOf(System.currentTimeMillis()),100,2);
			System.out.println(jsonObject);
//			JSONArray jsonArray=JSONArray.parseArray(jsonObject.get("msgs").toString());
//			System.out.println(jsonArray.get(0));
		}catch (Exception e){

		}

	}
}
